﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Collections;

namespace AMS.Common
{
    /// <summary>
    /// 一个本地化的框架库。
    /// 目前只实现了获取数据
    /// </summary>
    public class LocaleFramework
    {
        #region 单例和构造函数
        private static LocaleFramework instance;
        private static volatile object syncLock = new object();

        /// <summary>
        /// 唯一一实例
        /// </summary>
        internal static LocaleFramework Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncLock)
                    {
                        if (instance == null)
                        {
                            instance = new LocaleFramework();
                        }
                    }
                }

                return instance;
            }
        }

        Dictionary<string, Dictionary<string, string>> resourceRespository;
        private LocaleFramework()
        {
            resourceRespository = new Dictionary<string, Dictionary<string, string>>();
            AddDefaultResourceFiles();
        }
        #endregion

        #region 公有接口
        /// <summary>
        /// 添加资源模块
        /// </summary>
        /// <param name="dllFileName"></param>
        public static void AddResourceModule(string dllFileName)
        {
            Instance.AddResource(dllFileName);
        }

        /// <summary>
        /// 获取Key对应的资源
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetString(string key)
        {
            return GetString(key, CultureInfo.CurrentCulture);
        }

        /// <summary>
        /// 如果存在相关的KEY，则返回其对应的值，否则返回参数key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public static string GetString(string key, CultureInfo culture)
        {
            foreach (string rcFile in Instance.resourceRespository.Keys)
            {
                Dictionary<string, string> resources = Instance.resourceRespository[rcFile];
                if (resources.ContainsKey(key))
                {
                    return resources[key];
                }
            }

            return key;
        }

        /// <summary>
        /// 获取已格式化的字符串
        /// </summary>
        /// <param name="key"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string GetFormattedString(string key, params object[] args)
        {
            return GetFormattedString(key, CultureInfo.CurrentCulture, args);
        }

        /// <summary>
        /// 获取已格式化的字符串
        /// </summary>
        /// <param name="key"></param>
        /// <param name="culture"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string GetFormattedString(string key, CultureInfo culture, params object[] args)
        {
            string format = GetString(key, culture);
            if (args == null || args.Length == 0)
            {
                return format;
            }

            return string.Format(format, args);
        }
        #endregion

        #region Private函数
        /// <summary>
        /// 添加默认的资源文件
        /// </summary>
        private void AddDefaultResourceFiles()
        {
            string[] rcFiles = Directory.GetFiles(".", "*.amsrc.dll");
            foreach (string file in rcFiles)
            {
                AddResource(file);
            }
        }

        /// <summary>
        /// 添加资源文件
        /// </summary>
        /// <param name="dllFileName"></param>
        /// <exception cref="AmsResourceException">当资源文件重复加载</exception>
        public void AddResource(string dllFileName)
        {
            if (!File.Exists(dllFileName))
            {
                return;
            }

            string rcFileName = Path.GetFileNameWithoutExtension(dllFileName);
            if (resourceRespository.ContainsKey(rcFileName))
            {
                throw new AmsResourceException(GetFormattedString("@FileCannotBeLoadedTwice", dllFileName));
            }

            var resources = new Dictionary<string, string>();
            Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllFileName);
            string[] names = assembly.GetManifestResourceNames();

            foreach (string name in names)
            {
                Stream stream = assembly.GetManifestResourceStream(name);
                ResourceReader reader = new ResourceReader(stream);
                IDictionaryEnumerator ie = reader.GetEnumerator();
                while (ie.MoveNext())
                {
                    string key = ie.Key.ToString();
                    if (!resources.ContainsKey(key))
                    {
                        resources.Add(key, ie.Value.ToString());
                    }
                }

                reader.Close();
                stream.Close();
            }

            resourceRespository.Add(rcFileName, resources);
        }
        #endregion
    }
}
